<?php

namespace helper\tencent;

class QQ
{
    const VERSION = "2.0";
    const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";
    const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";
    const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";

    function __construct($config)
    {
        $this->appid = $config["appid"];
        $this->appkey = $config["appkey"];
        $this->callback = $config['callback'];
    }

    /**
     * 获取QQconnect Login 跳转到的地址值
     * @return void
     */
    public function login()
    {
        $state = md5(uniqid(rand(), TRUE));
        $_SESSION['Oauth_state'] = $state;

        // 构造请求参数列表
        $keysArr = array(
            "response_type" => "code",
            "client_id" => $this->appid,
            "redirect_uri" => $this->callback,
            "state" => $state
        );

        $login_url = self::GET_AUTH_CODE_URL . '?' . http_build_query($keysArr);

        header("Location:$login_url");
    }

    /**
     * 获取access_token值
     * @return string 返回包含access_token,过期时间的数组
     */
    public function callback()
    {
        if ($_GET['state'] != $_SESSION['Oauth_state']) {
            exit("<h2>The state does not match. You may be a victim of CSRF.</h2>");
        }
        // 请求参数列表
        $keysArr = array(
            "grant_type" => "authorization_code",
            "client_id" => $this->appid,
            "redirect_uri" => $this->callback,
            "client_secret" => $this->appkey,
            "code" => $_GET['code'],
            //"state" => $state,
        );

        // 构造请求access_token的url
        $token_url = self::GET_ACCESS_TOKEN_URL . '?' . http_build_query($keysArr);
        $response = $this->get_curl($token_url);

        if (strpos($response, "callback") !== false) {

            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos - 1);
            $msg = json_decode($response);

            if (isset($msg->error)) {
                exit('<h3>error:</h3>' . $msg->error . '<h3>msg  :</h3>' . $msg->error_description);
            }
        }

        $params = array();
        parse_str($response, $params);
        return $params["access_token"];
    }

    /**
     * 获取client_id 和 openid
     * @param string $access_token access_token验证码
     * @return string
     * */
    public function getOpenid($access_token)
    {
        // 请求参数列表
        $keysArr = array(
            "access_token" => $access_token
        );

        $graph_url = self::GET_OPENID_URL . '?' . http_build_query($keysArr);
        $response = $this->get_curl($graph_url);

        // 检测错误是否发生
        if (strpos($response, "callback") !== false) {

            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos - 1);
        }

        $user = json_decode($response);
        if (isset($user->error)) {
            exit('<h3>error:</h3>' . $user->error . '<h3>msg  :</h3>' . $user->error_description);
        }

        //------记录openid
        return $user->openid;
    }

    /**
     * 获取用户信息
     * @param $app_id
     * @param $token
     * @param $openid
     * @return array|false
     */
    public function getUserInfo($app_id, $token, $openid)
    {
        $url = 'https://graph.qq.com/user/get_user_info?oauth_consumer_key=' . $app_id . '&access_token=' . $token . '&openid=' . $openid . '&format=json';
        $str = $this->get_curl($url);
        if (!$str) {
            return false;
        }
        return json_decode($str, true);
    }

    public function get_curl($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Linux; U; Android 4.4.1; zh-cn) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.5 Mobile Safari/533.1');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $ret = curl_exec($ch);
        curl_close($ch);
        return $ret;
    }
}